﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Globalization;
using System.Text.RegularExpressions;
using TCL.EO;
using System.Text;
using System.Net.Sockets;
using System.IO;
using System.Collections.ObjectModel;
using System.Collections;

namespace TCL.FUNC
{
    public class CheckEx
    {
        public static Boolean IsBase64String(String sInput)
        {
            sInput = StringEx.Trim(sInput);
            return (sInput.Length % 4 == 0) && Regex.IsMatch(sInput, @"^[a-zA-Z0-9\+/]*={0,3}$", RegexOptions.None);
        }

        public static Boolean IsNumeric(String sInput, TypeCode tType)
        {
            Boolean bRet = false; Int16 iInt16; Int32 iInt32; Int64 iInt64; Decimal dDecimal; Double dDouble;
            switch (tType)
            {
                case TypeCode.Int16: bRet = Int16.TryParse(sInput, out iInt16); break;
                case TypeCode.Int32: bRet = Int32.TryParse(sInput, out iInt32); break;
                case TypeCode.Int64: bRet = Int64.TryParse(sInput, out iInt64); break;
                case TypeCode.Decimal: bRet = Decimal.TryParse(sInput, out dDecimal); break;
                case TypeCode.Double: bRet = Double.TryParse(sInput, out dDouble); break;
                default: bRet = false; break;
            }
            return bRet;
        }

        public static Boolean IsDateTime(String sInput, String sFormat = "")
        {
            DateTime tTemp = DateTime.MinValue;
            if (String.IsNullOrEmpty(sFormat))
                DateTime.TryParse(sInput, out tTemp);
            else
                DateTime.TryParseExact(sInput, sFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out tTemp);
            if (tTemp > DateTime.MinValue)
                return true;
            else
                return false;
        }

        public static Boolean IsUrl(String sInput)
        {
            Regex urlchk = new Regex(@"((file|gopher|news|nntp|telnet|http|ftp|https|ftps|sftp)://)+(([a-zA-Z0-9\._-]+\.[a-zA-Z]{2,15})|([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}))(/[a-zA-Z0-9\&amp;%_\./-~-]*)?", RegexOptions.Singleline | RegexOptions.IgnoreCase);
            //return Uri.TryCreate(strInput, UriKind.RelativeOrAbsolute);
            return Uri.IsWellFormedUriString(sInput, UriKind.RelativeOrAbsolute);
        }

        public static Boolean IsPasswordStrength(String sInput)
        {
            return Regex.IsMatch(sInput, @"^(?=.*[A-Z])(?=.*\d)(?!.*(.)\1\1)[a-zA-Z0-9@]{6,12}$");
            //return Regex.IsMatch(pwd, @"^.{6,}(?<=\d.*)(?<=[^a-zA-Z0-9].*)$");
        }

        public static Boolean IsDataTable(DataTable dtInput)
        {
            if (dtInput != null && dtInput.Rows.Count > 0)
                return true;
            else
                return false;
        }

        public static Boolean IsDataSet(DataSet dsInput, Int16 index)
        {
            if (dsInput == null)
                return false;
            if ((index + 1) > dsInput.Tables.Count)
                return false;
            return CheckEx.IsDataTable(dsInput.Tables[index]);
        }

        public static Boolean IsObject(Object objInput)
        {
            if (objInput != null)
                return true;
            else
                return false;
        }

        public static Boolean IsArray(Array arrInput)
        {
            if (arrInput != null && arrInput.Length > 0)
                return true;
            else
                return false;
        }

        public static Boolean IsSortedList(SortedList stlInput)
        {
            if (stlInput != null && stlInput.Count > 0)
                return true;
            else
                return false;
        }

        public static Boolean IsCollection<T>(Collection<T> cltInput)
        {
            if (cltInput != null && cltInput.Count > 0)
                return true;
            else
                return false;
        }

        public static Boolean IsListObject<T>(List<T> lstInput)
        {
            if (lstInput != null && lstInput.Count > 0)
                return true;
            else
                return false;
        }

        public static Boolean IsKeyValueEO(KeyValueEO objInput)
        {
            if (CheckEx.IsObject(objInput) && !String.IsNullOrEmpty(objInput.K) && !String.IsNullOrEmpty(objInput.V) && CheckEx.IsNumeric(objInput.K, TypeCode.Int64))
                return true;
            else
                return false;
        }

        //public static Boolean ValidateObject(object objInput, Int16 iTypeObject)
        //{
        //    String strInput = Convert.ToString(objInput);
        //    switch (iTypeObject)
        //    {
        //        case 11: //Valid Email
        //            if (!string.IsNullOrEmpty(strInput))
        //            {
        //                string strRegex = @"^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}" +
        //                      @"\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\" +
        //                      @".)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$";
        //                Regex re = new Regex(strRegex);
        //                if (re.IsMatch(strInput))
        //                    return true;
        //                else
        //                    return false;
        //            }
        //            else
        //                return false;
        //            break;

        //        case 21: //Valid Number  Int16
        //            Int16 value21 = 0;
        //            return Int16.TryParse(strInput, out value21);
        //            break;

        //        case 22: //Valid Number  int
        //        case 23: //Valid Number  Int32
        //            Int32 value23 = 0;
        //            return Int32.TryParse(strInput, out value23);
        //            break;

        //        case 24: //Valid Number  Int64
        //            Int64 value24 = 0;
        //            return Int64.TryParse(strInput, out value24);
        //            break;

        //        case 25: //Valid Number  Decimal, Numeric, SmallMoney, Money
        //            Decimal value25;
        //            return Decimal.TryParse(strInput, out value25);
        //            break;

        //        case 26: //Valid Number  Single, Real
        //            Single value26;
        //            return Single.TryParse(strInput, out value26);
        //            break;

        //        case 27: //Valid Number  Double, Float
        //            Double value27;
        //            return Double.TryParse(strInput, out value27);
        //            break;

        //        case 28: //Valid TinyInt
        //            Byte value28;
        //            return Byte.TryParse(strInput, out value28);
        //            break;

        //        case 31: //Valid DateTime, SmallDatetime, Date
        //            DateTime value31;
        //            return DateTime.TryParse(strInput, out value31);
        //            break;

        //        case 41: //Valid Boolean, Bit
        //            Boolean value41;
        //            return Boolean.TryParse(strInput, out value41);
        //            break;

        //        case 51: //Valid char, nchar, varchar, nvarchar, text, ntext
        //            String value51;
        //            //return String.TryParse(strInput, out value51);
        //            return true;
        //            break;
        //    }
        //    return false;
        //}



        public static Boolean IsValidEmail(String sInput)
        {
            try
            {
                var addr = new System.Net.Mail.MailAddress(sInput);
                return true;
            }
            catch
            {
                return false;
            }
        }

        public static Boolean IsExistsEmail(String sInput)
        {
            Boolean isExist = false;
            try
            {
                sInput = StringEx.Trim(sInput);
                KeyValueDataEO objMX = EMAIL_MX().Find(n => StringEx.CompareEx(n.K, sInput));

                if (String.IsNullOrEmpty(sInput) || objMX == null)
                    return false;
                else if (!CheckEx.IsValidEmail(sInput))
                    return false;


                TcpClient tClient = new TcpClient(objMX.V, Convert.ToInt32(objMX.D));
                string CRLF = "\r\n";
                byte[] dataBuffer;
                string ResponseString;
                NetworkStream netStream = tClient.GetStream();
                StreamReader reader = new StreamReader(netStream);
                ResponseString = reader.ReadLine();
                /* Perform HELO to SMTP Server and get Response */
                dataBuffer = BytesFromString("HELO KirtanHere" + CRLF);
                netStream.Write(dataBuffer, 0, dataBuffer.Length);
                ResponseString = reader.ReadLine();
                dataBuffer = BytesFromString("MAIL FROM:<it.site44.com@gmail.com>" + CRLF);
                netStream.Write(dataBuffer, 0, dataBuffer.Length);
                ResponseString = reader.ReadLine();
                /* Read Response of the RCPT TO Message to know from google if it exist or not */
                dataBuffer = BytesFromString("RCPT TO:<" + sInput + ">" + CRLF);
                netStream.Write(dataBuffer, 0, dataBuffer.Length);
                ResponseString = reader.ReadLine();
                if (GetResponseCode(ResponseString) == 250)
                {
                    isExist = true;
                }
                /* QUITE CONNECTION */
                dataBuffer = BytesFromString("QUITE" + CRLF);
                netStream.Write(dataBuffer, 0, dataBuffer.Length);
                tClient.Close();
            }
            catch (Exception ex)
            {
                (new Logs()).WriteLog_To_DB(new LogEO(ex.ToString(), ConstEx.Log_iType.EXCEPTION), false);
            }
            return isExist;
        }

        private static Byte[] BytesFromString(String str)
        {
            return Encoding.ASCII.GetBytes(str);
        }

        private static Int32 GetResponseCode(String ResponseString)
        {
            return Int32.Parse(ResponseString.Substring(0, 3));
        }

        public static List<KeyValueDataEO> EMAIL_MX()
        {
            List<KeyValueDataEO> lst = new List<KeyValueDataEO>();
            lst.Add(new KeyValueDataEO("@nguyenmanhthang.net", "mx2.zohomail.com", "25"));
            lst.Add(new KeyValueDataEO("@gmail.com", "gmail-smtp-in.l.google.com", "25"));
            lst.Add(new KeyValueDataEO("@yahoo.com", "mta6.am0.yahoodns.net", "25"));
            lst.Add(new KeyValueDataEO("@yahoo.com.vn", "mx-apac.mail.gm0.yahoodns.net", "25"));
            lst.Add(new KeyValueDataEO("@hotmail.com", "mx1.hotmail.com", "25"));
            lst.Add(new KeyValueDataEO("@outlook.com", "mx3.hotmail.com", "25"));
            lst.Add(new KeyValueDataEO("@outlook.com.vn", "mx3.hotmail.com", "25"));
            lst.Add(new KeyValueDataEO("@myduc.edu.vn", "alt1.aspmx.l.google.com", "25"));
            lst.Add(new KeyValueDataEO("@hou.edu.vn", "alt1.aspmx.l.google.com", "25"));
            lst.Add(new KeyValueDataEO("@hanoi.edu.vn", "alt1.aspmx.l.google.com", "25"));
            return lst;
        }
    }
}